﻿using System;
using System.Reflection;
using System.Repository.Base;
using System.Runtime.Loader;
using Application.Infrastructure;
using Autofac; 

namespace Ubiquity.Web.Ioc
{
    public class IocConfig
    {
        public static IContainer AutofacContainer;
        public static ContainerBuilder Build()
        {  //注册服务进 IServiceCollection

            ContainerBuilder builder = new ContainerBuilder();
            //注册服务
            //builder.RegisterType<SysOperationLogService>().As<SysOperationLogService>(); 
           

            //新模块组件注册
            builder.RegisterModule<DefaultModuleRegister>();
            return builder;
        }

        public static TService Resolve<TService>()
        {
            return AutofacContainer.Resolve<TService>();
        }

    }
    /// <summary>
    /// 默认模块注册
    /// </summary>
    public class DefaultModuleRegister : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {

            builder.RegisterType<DbContextConfig>().As<IDbContextConfig>();//数据库上下文 配置
            builder.RegisterType<Log>().As<ILog>();//服务日志 

            //Autofac注入有多种不同的生命周期类型，分别为InstancePerLifetimeScope、SingleInstance、InstancePerDependency等，各位在项目中按需选择即可。 
            //注册当前程序集中以“Ser”结尾的类,暴漏类实现的所有接口，生命周期为PerLifetimeScope 

            builder.RegisterAssemblyTypes(GetAssembly("System.Application"))
                .Where(t => t.Name.EndsWith("Service"))
                .InstancePerDependency()
                .InstancePerDependency();//实例的依赖 

            //builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
            builder.RegisterAssemblyTypes(GetAssembly("System.Repository"))
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces()//接口依赖
                .InstancePerLifetimeScope();



            ////注入Data层的Repository类
            //builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerDependency();
            ////批量注入Core层的类
            //builder.RegisterAssemblyTypes(typeof(UserCore).Assembly)
            //    .Where(t => t.Name.EndsWith("Core"))
            //    .AsImplementedInterfaces();

        }

        public static Assembly GetAssembly(string assemblyName)
        {
            var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(AppContext.BaseDirectory + $"{assemblyName}.dll");
            return assembly;
        }
    }
}
